package com.duan.laugh.file.controller;

import com.duan.laugh.common.core.util.R;
import com.duan.laugh.starter.minio.core.MinioTemplate;
import com.duan.laugh.starter.minio.vo.FileVO;
import com.duan.laugh.file.api.pojo.eneity.File;
import com.duan.laugh.file.service.FileService;
import com.duan.laugh.file.util.FileUtil;
import io.minio.messages.Bucket;
import io.minio.messages.Item;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 文件上传、下载
 *
 * @author duanjw
 */
@RestController
public class FileController {
    @Autowired
    private MinioTemplate template;
    @Autowired
    private FileService fileService;

    /**
     * 新增bucket
     */
    @SneakyThrows
    @PostMapping("/bucket")
    public Bucket insertBucket() {
        final String bucketName = FileUtil.getBucketName();
        template.insertBucket(bucketName);
        return template.getBucket(bucketName).get();
    }

    /**
     * 查看我的bucket
     *
     * @return
     */
    @SneakyThrows
    @GetMapping("/my/bucket")
    public Bucket getBucket() {
        return template.getBucket(FileUtil.getBucketName()).orElseThrow(() -> new IllegalArgumentException("Bucket Name not found!"));
    }

    /**
     * 在我的bucket上传文件
     */
    @SneakyThrows
    @PostMapping("/file")
    public File uploadFile(@RequestBody MultipartFile file) {
        String name = file.getOriginalFilename();
        final String bucketName = FileUtil.getBucketName();
        return fileService.uploadFile(file, bucketName, name);
    }

    /**
     * 在我的bucket下载文件
     * @param request
     * @param response
     * @param id
     */
    @GetMapping("/file/{id}")
    public void download(HttpServletRequest request, HttpServletResponse response, @PathVariable String id) {
        final File dbFile = fileService.getById(id);
        final String filename = dbFile.getName();
        FileUtil.download(request, response, template.getFile(FileUtil.getBucketName(), dbFile.getFilename()), filename);
    }

    /**
     * 根据id删除文件
     */
    @SneakyThrows
    @DeleteMapping("/file/{id}")
    public R deleteFile(@PathVariable Long id) {
        return R.ok(fileService.deleteFile(FileUtil.getBucketName(), id));
    }

    /**以下bucket由调用者指定**/

    /**
     * 指定bucket查看bucket
     * @param bucketName
     * @return
     */
    @SneakyThrows
    @GetMapping("/bucket/{bucketName}")
    public Bucket getBucket(@PathVariable String bucketName) {
        return template.getBucket(bucketName).orElseThrow(() -> new IllegalArgumentException("Bucket Name not found!"));
    }

    /**
     * 查询所有bucket
     *
     * @return
     */
    @SneakyThrows
    @GetMapping("/bucket")
    public List<Bucket> selectBucket() {
        return template.selectBucket();
    }

    /**
     * 指定bucket删除bucket
     *
     * @param bucketName
     */
    @SneakyThrows
    @DeleteMapping("/bucket/{bucketName}")
    @ResponseStatus(HttpStatus.ACCEPTED)
    public void deleteBucket(@PathVariable String bucketName) {
        template.deleteBucket(bucketName);
    }

    /**
     * 在指定的bucket上传文件
     */
    @SneakyThrows
    @PostMapping("/file/bucket/{bucketName}")
    public File uploadFile(@RequestBody MultipartFile file, @PathVariable String bucketName) {
        String filename = file.getOriginalFilename();
        return fileService.uploadFile(file, bucketName, filename);

    }

    /**
     * 在指定的bucket上传文件，并指定文件名
     */
    @SneakyThrows
    @PostMapping("/file/bucket/{bucketName}/filename/{filename}")
    public File uploadFile(@RequestBody MultipartFile file, @PathVariable String bucketName, @PathVariable String filename) {
        return fileService.uploadFile(file, bucketName, filename);
    }

    /**
     * 在指定的bucket中查询文件
     * @param bucketName
     * @param filename
     * @return
     */
    @SneakyThrows
    @GetMapping("/file/bucket/{bucketName}/filename/{filename}")
    public List<Item> selectFile(@PathVariable String bucketName, @PathVariable String filename) {
        return template.selectFileByPrefix(bucketName, filename, true);
    }

    /**
     * 在指定的bucket中分享文件
     * @param bucketName
     * @param filename
     * @param expires
     * @return
     */
    @SneakyThrows
    @GetMapping("/file/bucket/{bucketName}/filename/{filename}/expires/{expires}")
    public Map<String, Object> getShareURL(@PathVariable String bucketName, @PathVariable String filename, @PathVariable Integer expires) {
        Map<String, Object> responseBody = new HashMap<>(8);
        // Put Object info
        responseBody.put("bucket", bucketName);
        responseBody.put("object", filename);
        responseBody.put("url", template.getShareURL(bucketName, filename, expires));
        responseBody.put("expires", expires);
        return responseBody;
    }

    /**
     * 在指定的bucket删除文件
     * @param bucketName
     * @param filename
     */
    @SneakyThrows
    @ResponseStatus(HttpStatus.ACCEPTED)
    @DeleteMapping("/file/bucket/{bucketName}/filename/{filename}")
    public void deleteFile(@PathVariable String bucketName, @PathVariable String filename) {
        template.deleteFile(bucketName, filename);
    }
}
